package algebra.query.indexing;

import java.util.ArrayList;
import java.util.List;

import option.KBVocabulary;

import utils.exception.CoreReasoningException;

import entities.assertion.ConceptAssertion;
import entities.concept.Concept;
import kb.DescriptionLogicsKB;
import algebra.op.PrimaryOP;
import algebra.query.indexing.DescriptionIndex;
import algebra.query.od.OrderDep;
import algebra.query.od.OrderDepNoop;
import algebra.query.pd.PdConcept;
import algebra.query.pd.ProjDesc;
import algebra.visitors.AlgebraicOPEvaluator;

/**
 * The PI is a special secondary index (T, T):un
 * 
 * @author j55wu
 * 
 */
public class PrimaryIndex extends CachedIndex {

	private final String name;
	private List<ConceptAssertion> results;
	private final DescriptionLogicsKB kb;

	private DescriptionIndex di;

	public Concept getCi() {
		return KBVocabulary.CONCEPT_TOP;
	}

	public OrderDep getOdi() {
		return new OrderDepNoop();
	}

	public ProjDesc getPdi() {
		return new PdConcept(KBVocabulary.CONCEPT_TOP);
	}

	public PrimaryIndex(DescriptionLogicsKB kb) {
		super();
		this.kb = kb;
		this.name = Integer.toString(this.toSerializedString().hashCode())
				+ "PI";
		this.results = new ArrayList<ConceptAssertion>();
	}

	public DescriptionLogicsKB getKB() {
		return this.kb;
	}

	@Override
	public void buildIndex(String indexloc) {
		String loc = indexloc;
		if(indexloc == null || indexloc.trim().equals("")){
			//use teh default location
			loc = indexDir;
		}
		PrimaryOP pq = new PrimaryOP(kb);
		AlgebraicOPEvaluator eval = new AlgebraicOPEvaluator();
		try {
			results = pq.acceptVisitor(eval);
		} catch (CoreReasoningException e) {
			e.printStackTrace();
		}
		try {
			this.di = AlgebraicOPEvaluator.indexingQueryResults(results, null);
			// materialize
			if (buildSave) {
				String sfn = name + extensionIndex;
				CachedIndex.serializeCacheIndex(this.toSerializedString(),
						this.di, null, loc + sfn);
			}
		} catch (CoreReasoningException e) {
			e.printStackTrace();
		}
	}

	@Override
	public DescriptionIndex getDescriptionIndex() {
		return this.di;
	}

	public void setDescriptionIndex(DescriptionIndex di) {
		this.di = di;
	}

	@Override
	public String getName() {
		return this.toString();
	}

	@Override
	public String toString() {
		return this.kb.getKBName() + serializedNameSep + "[PI]"
				+ serializedNameSep + "un";
	}

	@Override
	public String toSerializedString() {
		return this.toString();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((kb == null) ? 0 : kb.hashCode());
		return result;
	}
	//
	// @Override
	// public boolean equals(Object obj) {
	// if (this == obj)
	// return true;
	// if (obj == null)
	// return false;
	// if (!(obj instanceof PrimaryIndex))
	// return false;
	// PrimaryIndex other = (PrimaryIndex) obj;
	// if (kb == null) {
	// if (other.kb != null)
	// return false;
	// } else if (!kb.equals(other.kb))
	// return false;
	// if (kbname == null) {
	// if (other.kbname != null)
	// return false;
	// } else if (!kbname.equals(other.kbname))
	// return false;
	// return true;
	// }

}
